package com.hnchances.grade.shiro;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hnchances.grade.common.utils.JWTUtils;
import com.hnchances.grade.entity.MenuEntity;
import com.hnchances.grade.entity.UserEntity;
import com.hnchances.grade.service.MenuService;
import com.hnchances.grade.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

/**
 * doGetAuthenticationInfo方法用于->认证:校验帐号和密码
 * doGetAuthorizationInfo方法用于->授权:授予角色和权限
 */

@Slf4j
public class ShiroRealm extends AuthorizingRealm {

    /**
     * 角色
     * 不用建了  0 学生 1老师 2 管理员
     */
    /*@Autowired
    private RoleService roleService;*/
    /**
     * 菜单  需要建立对应的菜单权限
     */
    @Autowired
    private MenuService menuService;
    @Autowired
    private UserService userService;

    /**
     * 因为是自己定义的Token，shiro无法识别，需要修改Realm中的supports方法，使 shiro 支持自定义token。
     * @param token
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JWTToken;
    }



    /**
     * 认证:校验帐号和密码
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String token = (String) authenticationToken.getCredentials();
        //从token中获取用户名
        String userName = JWTUtils.getUsername(token);
        //获取数据库中存取的用户，密码是加密后的
//        User user = userService.selectByUserName(username);
        UserEntity user = userService.getOne(
                new QueryWrapper<UserEntity>().eq("userName", userName));
        if (user != null) {
            // 密码验证
            if (!JWTUtils.verify(token, userName, user.getPassWord())) {
                // 密码不正确
                throw new IncorrectCredentialsException();
            }
            return new SimpleAuthenticationInfo(token, token, getName());
        } else {
            throw new UnknownAccountException();
        }
    }

    /**
     * 授权:授予角色和权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //获取用户名
        String userName = JWTUtils.getUsername(principals.toString());
        //根据用户名查询用户
        UserEntity user = userService.getOne(
                new QueryWrapper<UserEntity>().eq("userName", userName));
        //实例化一个授权信息
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        if (user != null) {
            //赋予角色
            Integer identity = user.getIdentity();
            if (identity == 0){
                log.info("学生角色");
                info.addRole("学生");
            }else if (identity == 1){
                log.info("老师角色");
                info.addRole("老师");
            }else {
                log.info("管理员角色");
                info.addRole("管理员");
            }
            //赋予资源
//            List<Menu> permissions = menuService.selectPermsByUserId(user.getId());
            List<MenuEntity> permissions = menuService.list(new QueryWrapper<MenuEntity>().eq("role", user.getIdentity()));
            for (MenuEntity permission : permissions) {
                //将权限添加授权信息中
                info.addStringPermission(permission.getPerms());
            }
        }
        return info;
    }

}

